/*
 *
 * The WanderDemo sketch
 *
 */

// The wanderer agent.
Agent wanderer;
// It's steering behaviours
Wander wander;
// Are we paused?
boolean pause;
// Is this information panel being displayed?
boolean showInfo;

// Should we draw the wandering circle?
static boolean annotate;

// Boundaries or torus map?
static boolean boundaries;


// Initialisation
void setup() {
  size(1000,600); // Large display window
  pause = false;
  showInfo = true;
  
  // Create the agent
  wanderer = new Agent(10, 10, randomPoint());
  
  PVector target = randomPoint();
  // Create a Wander behaviour
  //    Wander(Agent a, float alph, float wRadius, float wDist) 
  wander = new Wander(wanderer, 10, 10, 100);
  // Add the behaviour to the agent
  wanderer.behaviours.add(wander);

  // Don't draw annotations
  WanderDemo.annotate = false;
  // Torus map to start with
  WanderDemo.boundaries = false;

  smooth(); // Anti-aliasing on
}

// Pick a random point in the display window
PVector randomPoint() {
  return new PVector(random(width), random(height));
}

// The draw loop
void draw() {
  // Clear the display
  background(255); 
  
  // Move forward one step in steering simulation
  if (!pause) wanderer.update();
  

  // Draw the agents
  wanderer.draw();
  
  // Draw the information panel
  if (showInfo) drawInfoPanel();
  
  if (WanderDemo.boundaries) drawBoundaries();
}
  
// Draw the information panel!
void drawInfoPanel() {
  pushStyle(); // Push current drawing style onto stack
  fill(0);
  ArrayList<String> infoPanel = buildInfoPanel();
  int yOffset= 0;
  for (String entry : infoPanel) {
     text(entry, 10, 20+yOffset);
     yOffset += 15;
  }
  popStyle(); // Retrieve previous drawing style
}

// Build the information panel
ArrayList<String> buildInfoPanel() {
  ArrayList<String> res = new ArrayList<String>();
  res.add("1 - toggle display");
  res.add("2 - toggle annotation");
  res.add("3 - toggle boundaries (torus map or not)");
  res.add("Space - play/pause");
  res.add("Mass (q/a) = " + wanderer.mass);
  res.add("Max. Force (w/s) = " + wanderer.maxForce);
  res.add("Max. Speed (e/d) = " + wanderer.maxSpeed);
  res.add("Target Jitter (r/f) = " + wander.targetJitter);
  res.add("Wander Radius (t/g) = " + wander.wanderRadius);
  res.add("Wander Distance (y/h) = " + wander.wanderDistance);
  res.add("Click to move the target");
  return res;
}

//Draw boundaries
void drawBoundaries() {
  pushStyle();
  stroke(200, 20, 20);
  strokeWeight(4);
  line(0,0, width, 0);
  line(0,0, 0, height);
  line(width-1,0, width-1, height-1);
  line(0,height-1, width-1, height-1);
  popStyle();
}

/*
 * Input handlers
 */

// Mouse clicked, so move the target
void mouseClicked() {
   PVector newTarget = new PVector(mouseX, mouseY);
   wander.target = newTarget; 
}

// Key pressed
void keyPressed() {
   if (key == ' ') {
       togglePause();
     
   } else if (key == '1' || key == '!') {
       toggleInfo();
     
   } else if (key == '2' || key == '"') {
       toggleAnnotate();
     
   } else if (key == '3' || key == '£') {
       toggleBoundaries();
    
     // Vary the agent's mass
   } else if (key == 'q' || key == 'Q') {
     wanderer.incMass();
   } else if (key == 'a' || key == 'A') {
     wanderer.decMass();
     
     // Vary the agent's maximum force
   } else if (key == 'w' || key == 'W') {
     wanderer.incMaxForce();
   } else if (key == 's' || key == 'S') {
     wanderer.decMaxForce();

     // Vary the agent's maximum speed
   } else if (key == 'e' || key == 'E') {
     wanderer.incMaxSpeed();
   } else if (key == 'd' || key == 'D') {
     wanderer.decMaxSpeed();
   
    // Vary target jitter
   } else if (key == 'r' || key == 'R') {
     wander.incTargetJitter();
   } else if (key == 'f' || key == 'F') {
     wander.decTargetJitter();
     
     // Vary wander radius
   } else if (key == 't' || key == 'T') {
     wander.incWanderRadius();
   } else if (key == 'g' || key == 'G') {
     wander.decWanderRadius();
   
        // Vary wander radius
   } else if (key == 'y' || key == 'Y') {
     wander.incWanderDistance();
   } else if (key == 'h' || key == 'H') {
     wander.decWanderDistance();
   }
}

// Toggle the pause state
void togglePause() {
     if (pause) {
       pause = false; 
     } else {
       pause = true;
     }
}

// Toggle the display of the information panel
void toggleInfo() {
     if (showInfo) {
       showInfo = false; 
     } else {
       showInfo = true;
     }
}

// Toggle annotations
void toggleAnnotate() {
    if (WanderDemo.annotate) {
	WanderDemo.annotate = false;
    } else {
       WanderDemo.annotate = true;
    } 
}

// Toggle boundaries
void toggleBoundaries() {
    if (WanderDemo.boundaries) {
       WanderDemo.boundaries = false;
    } else {
	WanderDemo.boundaries = true;
    } 
}
